<?php


namespace App\Http\Utils;


use Firebase\JWT\JWT;

class Token
{

    private $token = null;
    private $key = "!@#$%^&ZUHGvbbfgtgf";

    private $jwt=null;


    //反馈消息
    private  $msg=false;

    //用户信息
    private $user=[];

    //用户需要保存的信息
    private  $data=[];

    static private $instance;

    private function __construct()
    {
    }

    private function __clone()
    {
        // TODO: Implement __clone() method.
    }

    public static function getInstance()
    {
        if (!self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * 生成token
     * @param array $data
     * @return $this
     *
     */
    public function generate(array $data = [])
    {

        $this->data=$data;
        $time = time();
        $this->token = JWT::encode([
            "iss" => config('app_host'), //jwt签发者
            "aud" => config('app_host'), //接收jwt的一方
            "iat" => $time, //jwt的签发时间
            "nbf" => $time,//定义在什么时间之前，某个时间点后才能访问
            "exp" => $time + 86400,// jwt的过期时间，过期时间必须要大于签发时间
            "data" => serialize($this->data),
        ], $this->key, 'HS256'); // Retrieves the generated token

        return $this;
    }

    /**
     * 获取token
     * @return string
     */
    public function getToken()
    {
        return (string)$this->token;
    }

    /**
     * 解密
     * @param $token
     * @return $this
     */
    public function decode($token)
    {
        $this->token=$token;
        try{
            $this->jwt=JWT::decode($this->token,$this->key, array('HS256'));
            $this->data=$this->getUserInfo();
            if(time()>$this->jwt->exp){ //是否过期
                $this->msg="token 过期";
            }
        }catch (\Exception $e){
            if(!empty($e->getMessage())){
                $this->msg=$e->getMessage();
            }
        }
        return $this;
    }

    /**
     * 获取用户信息
     * @return  $this
     */
    public function getUserInfo(){
        $this->user=unserialize($this->jwt->data);
        return $this->user;
    }

    /**
     * 获取信息
     */
    public function get(callable $fun){
        $res=$fun($this->getToken());
        if(empty($res)){
            $this->msg="token 有误";
        }
        return $this;
    }

    public function getError(){
        return $this->msg;
    }
    /**
     * 保存token
     * @param callable $fun
     * @return $this|string
     */
    public function  save(callable $fun){
        $fun($this->getToken());
        return $this;
    }


}